local cjson     = require "cjson"
local string    = require "string"
local table_new = require "table.new"
local table     = require "table"
local waf       = require "waf"

require "functions"

local _M={}

local function say_json(errcode,errmsg)
    ngx.header['Content-Type'] = 'application/json; charset=utf-8'
    ngx.status = ngx.HTTP_FORBIDDEN
    ngx.say(cjson.encode({errcode=errcode,errmsg=errmsg}))
    ngx.exit(ngx.status)
end

function _M.access(flag)
    if not flag then
        return
    end

    local content_length=tonumber(ngx.req.get_headers()['content-length'])
    local method=ngx.req.get_method()
    local ngxmatch=ngx.re.match

    if ngx.var.http_Acunetix_Aspect then
        ngx.exit(444)
    elseif ngx.var.http_X_Scan_Memo then
        ngx.exit(444)
    else
        if method=="POST" then
            local boundary = get_boundary()
            if boundary then
                local len = string.len
                local sock, err = ngx.req.socket()
                if not sock then
                    return
                end
                ngx.req.init_body(512 * 1024)
                sock:settimeout(0)
                local content_length = nil
                content_length=tonumber(ngx.req.get_headers()['content-length'])
                local chunk_size = 4096
                if content_length < chunk_size then
                    chunk_size = content_length
                end
                local size = 0
                while size < content_length do
                    local data, err, partial = sock:receive(chunk_size)
                    data = data or partial
                    if not data then
                        return
                    end
                    ngx.req.append_body(data)
                    if waf.body(data) then
                        say_json(403,"WAF禁止访问")
                        return true
                    end
                    size = size + len(data)
                    local m = ngxmatch(data,[[Content-Disposition: form-data;(.+)filename="(.+)\\.(.*)"]],'ijo')
                    if m then
                        if fileExtCheck(m[3]) then say_json(403,"WAF禁止访问(63)") end
                        filetranslate = true
                    else
                        if ngxmatch(data,"Content-Disposition:",'isjo') then
                            filetranslate = false
                        end
                        if filetranslate==false then
                            if body(data) then
                                return true
                            end
                        end
                    end
                    local less = content_length - size
                    if less < chunk_size then
                        chunk_size = less
                    end
                end
                ngx.req.finish_body()
            else
                ngx.req.read_body()
                local args = ngx.req.get_post_args()
                if not args then
                    return
                end
                for key, val in pairs(args) do
                    if type(val) == "table" then
                        if type(val[1]) == "boolean" then
                            return
                        end
                        data=table.concat(val, ", ")
                    else
                        data=val
                    end
                    if data and type(data) ~= "boolean" and body(data) then
                        if body(key) then
                            say_json(403,"WAF禁止访问(98)")
                            return
                        end
                    end
                end
            end
        end
    end
end


return _M
